﻿using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Xsl;
using Microsoft.SharePoint;

namespace SharePointPowerToys
{
    public class Helpers
    {
        #region GetFile
        /// <summary>
        /// GetFile
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public static string GetFile(string uri)
        {
            string results = string.Empty;
            if (uri.ToLower().StartsWith("http"))
            {
                results = GetWebFile(uri, true);
            }
            if (results == string.Empty)
            {
                results = GetSpFile(uri);
            }
            return results;
        }
        #endregion

        #region GetSpFile
        /// <summary>
        /// GetSpFile
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetSpFile(string fileName)
        {
            return GetSpFile(null, null, null, fileName);
        }

        /// <summary>
        /// GetSpFile
        /// </summary>
        /// <param name="folderName"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetSpFile(string folderName, string fileName)
        {
            return GetSpFile(null, null, folderName, fileName);
        }

        /// <summary>
        /// GetSpFile
        /// </summary>
        /// <param name="listName"></param>
        /// <param name="folderName"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetSpFile(string listName, string folderName, string fileName)
        {
            return GetSpFile(null, listName, folderName, fileName);
        }

        /// <summary>
        /// GetSpFile
        /// </summary>
        /// <param name="siteUrl"></param>
        /// <param name="listName"></param>
        /// <param name="folderName"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetSpFile(string siteUrl, string listName, string folderName, string fileName)
        {
            string contents = string.Empty;
            if (fileName == string.Empty)
            {
                return contents;
            }
            try
            {
                //Stream fileStream = new MemoryStream();
                if (fileName.StartsWith("http"))
                {
                    try
                    {
                        SPSecurity.RunWithElevatedPrivileges(delegate()
                        {
                            using (SPSite portalSite = new SPSite(fileName))
                            {
                                SPWeb web = portalSite.OpenWeb();
                                SPFile file = web.GetFile(fileName);
                                byte[] content = file.OpenBinary();
                                System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
                                contents = enc.GetString(content);
                            }
                        });
                    }
                    catch (Exception ex)
                    {
                        //MessageBox.Show(ex.ToString());
                    }
                }
                else
                {
                    if (String.IsNullOrEmpty(siteUrl))
                    {
                        siteUrl = HttpContext.Current.Request.Url.ToString();
                    }

                    if (String.IsNullOrEmpty(listName))
                    {
                        listName = "Style Library";
                    }
                    
                    if (String.IsNullOrEmpty(folderName))
                    {
                        folderName = "XSL Style Sheets";
                    }

                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        using (SPSite site = new SPSite(siteUrl))
                        {
                            using (SPWeb web = site.RootWeb)
                            {
                                SPDocumentLibrary library = (SPDocumentLibrary)web.Lists[listName];

                                string libraryRelativePath = library.RootFolder.SubFolders[folderName].ServerRelativeUrl;
                                string libraryPath = site.MakeFullUrl(libraryRelativePath);
                                string documentPath = libraryPath + "/" + fileName;

                                contents = web.GetFileAsString(documentPath);
                            }
                        }
                    });
                }
            }
            catch (Exception ex)
            {
                //Log this somewhere
            }
            return contents;
        }
        #endregion

        #region GetWebFile
        /// <summary>
        /// GetWebFile
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        public static string GetWebFile(string uri)
        {
            return GetWebFile(uri, false);
        }

        /// <summary>
        /// GetWebFile
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="ignoreErrors"></param>
        /// <returns></returns>
        public static string GetWebFile(string uri, bool ignoreErrors)
        {
            const int bufSizeMax = 65536;
            // max read buffer size conserves memory
            const int bufSizeMin = 8192;
            // min size prevents numerous small reads
            StringBuilder sb = new StringBuilder();
            // A WebException is thrown if HTTP request fails
            try
            {  
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {   
                    // Create an HttpWebRequest using WebRequest.Create (see .NET docs)!
                    WebRequest request = (WebRequest)WebRequest.Create(uri);
                    //Use the credentials of the app pool who certainly has access to what ever it is we need.
                    request.Credentials = System.Net.CredentialCache.DefaultCredentials;
                    // Execute the request and obtain the response stream
                    using (WebResponse response = (WebResponse)request.GetResponse())
                    {
                        using (Stream responseStream = response.GetResponseStream())
                        {
                            // Content-Length header is not trustable, but makes a good hint.
                            // Responses longer than int size will throw an exception here!
                            int length = (int)response.ContentLength;
                            // Use Content-Length if between bufSizeMax and bufSizeMin
                            int bufSize = bufSizeMin;
                            if (length > bufSize)
                            {
                                bufSize = length > bufSizeMax ? bufSizeMax : length;
                            }
                            // Allocate buffer and StringBuilder for reading response
                            byte[] buf = new byte[bufSize];
                            sb = new StringBuilder(bufSize);
                            // Read response stream until end
                            while ((length = responseStream.Read(buf, 0, buf.Length)) != 0)
                            {
                                sb.Append(Encoding.UTF8.GetString(buf, 0, length));
                            }
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                if (!ignoreErrors)
                {
                    sb.Append(ex.Message);
                }
            }
            return sb.ToString().Trim();
        }
        #endregion


        #region StringGet
        public static string StringGet(string value)
        {
            return StringGet(value, string.Empty);
        }
        public static string StringGet(string value, string defaultValue)
        {
            if (value == null)
            {
                return defaultValue;
            }
            if (value == string.Empty)
            {
                return defaultValue;
            }
            return value;
        }
        public static string StringGet(object value)
        {
            return StringGet(value.ToString(), string.Empty);
        }
        public static string StringGet(object value, string defaultValue)
        {
            return StringGet(value.ToString(), defaultValue);
        }
        #endregion

        #region TagGet
        public static string TagGet(string source, string tag)
        {
            return TagGet(source, tag, string.Empty, false);
        }
        public static string TagGet(string source, string tag, string defaultValue)
        {
            return TagGet(source, tag, defaultValue, false);
        }
        public static string TagGet(string source, string tag, string defaultValue, bool includeTag)
        {
            string results = string.Empty;
            try
            {
                int startLoc = source.ToLower().IndexOf("<" + tag.ToLower() + ">");
                if (startLoc > -1)
                {
                    int endLoc = source.ToLower().IndexOf("</" + tag.ToLower() + ">");
                    //if (endLoc > -1)
                    //{
                    //    endLoc += tag.Length + 2;
                    //}

                    string tempResults = source.Substring(startLoc, endLoc - startLoc);
                    startLoc = tempResults.IndexOf(">") + 1;
                    tempResults = tempResults.Substring(startLoc, tempResults.Length - startLoc);
                    results = tempResults;
                }
            }
            catch { }
            results = StringGet(results, defaultValue);
            if(includeTag)
            {
                results = "<" + tag + ">" + results + "</" + tag + ">";
            }
            return results;
        }
        #endregion

        #region TagContentsRemove
        public static string TagContentsRemove(string source, string tag)
        {
            string results = source;
            try
            {
                int startLoc = source.ToLower().IndexOf("<" + tag + ">");
                if (startLoc > -1)
                {
                    int endLoc = source.ToLower().IndexOf("</" + tag + "/>");
                    if (endLoc > -1)
                    {
                        endLoc += 13;
                    }
                    results = source.Remove(startLoc, endLoc - startLoc);
                }
            }
            catch { }
            return results;
        }
        #endregion

        #region FieldLookupValueGet
        public static string FieldLookupValueGet(SPListItem item, string fieldName)
        {
            string retValue = string.Empty;
            try
            {
                retValue = (new Microsoft.SharePoint.SPFieldLookupValue(item[fieldName].ToString())).LookupValue;
            }
            catch { }
            return retValue;
        }
        #endregion

        #region FieldValueGet
        public static string FieldValueGet(SPListItem item, string fieldName)
        {
            string retValue = string.Empty;
            try
            {
                retValue = item[fieldName].ToString();
            }
            catch { }
            return retValue;
        }
        #endregion

        #region FileNameGet
        public static string FileNameGet(string pathInfo)
        {
            string results = pathInfo; // string.Empty;

            try
            {
                int startLoc = pathInfo.LastIndexOf("/");

                // Check for trailing slash on Directories
                if (startLoc == pathInfo.Length - 1)
                {
                    pathInfo = pathInfo.Remove(pathInfo.Length - 1, 1);
                    //startLoc = pathinfo.LastIndexOf("/", pathinfo.Length - 2);
                    startLoc = pathInfo.LastIndexOf("/");
                }

                if (startLoc == -1)
                {
                    startLoc = 0;
                }
                else
                {
                    startLoc++;
                }
                int endLoc = pathInfo.LastIndexOf(".");
                if (endLoc == -1)
                {
                    endLoc = pathInfo.Length;
                }
                results = pathInfo.Substring(startLoc, endLoc - startLoc);
            }
            catch { }
            return results;
        }
        #endregion

        #region BuildNameValueCollection
        /// <summary>
        /// BuildNameValueCollection
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static NameValueCollection BuildNameValueCollection(string data)
        {
            return BuildNameValueCollection(data, '|');
        }
        /// <summary>
        /// BuildNameValueCollection
        /// </summary>
        /// <param name="data"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static NameValueCollection BuildNameValueCollection(string data, char separator)
        {
            NameValueCollection results = new NameValueCollection();
            if (data != null && data != "")
            {
                String[] parmString = data.Split(separator);
                try
                {
                    foreach (String parmPairString in parmString)
                    {
                        //String[] parmPair = parmPairString.Split('=');
                        //parms.Add(parmPair[0], parmPair[1]);
                        int startLoc = parmPairString.IndexOf("=");
                        if (startLoc > -1)
                        {
                            results.Add(parmPairString.Substring(0, startLoc), parmPairString.Substring(startLoc + 1, parmPairString.Length - startLoc - 1));
                        }
                    }
                }
                catch { }
            }
            return results;
        }
        #endregion

        #region TransformLoad
        /// <summary>
        /// TransformLoad
        /// </summary>
        /// <param name="transformFileUri"></param>
        /// <returns></returns>
        public static XslCompiledTransform TransformLoad(string transformFileUri)
        {
            XslCompiledTransform xslTransform = new XslCompiledTransform(false);
            string xslFile = GetFile(transformFileUri);
            if (xslFile != string.Empty)
            {
                StringReader sr = new StringReader(xslFile);
                XsltSettings xsltSettings = new XsltSettings();
                xsltSettings.EnableScript = true;
                XmlResolver xmlResolver = new XmlUrlResolver();
                xslTransform.Load(XmlReader.Create(sr), xsltSettings, xmlResolver);
            }
            return xslTransform;
        }
        #endregion

        #region TransformGetString
        /// <summary>
        /// TransformGetString
        /// </summary>
        /// <param name="xslTransform"></param>
        /// <param name="xmlReader"></param>
        /// <returns></returns>
        public static string TransformGetString(XslCompiledTransform xslTransform, XmlReader xmlReader)
        {
            string results = string.Empty;
            try
            {
                MemoryStream ms = new MemoryStream();
                XmlTextWriter xmlTextWriter = new XmlTextWriter(ms, Encoding.ASCII);
                StreamReader rd = new StreamReader(ms);
                xslTransform.Transform(xmlReader, null, xmlTextWriter);
                ms.Position = 0;
                results = rd.ReadToEnd();
                rd.Close();
                ms.Close();
            }
            catch (Exception ex)
            {
            }
            return results;
        }
        #endregion
                

        #region GetElementString
        public static string GetElementString(XElement item, string element)
        {
            return GetElementString(item, element, string.Empty);
        }
        public static string GetElementString(XElement item, string element, string defaultValue)
        {
            string results = string.Empty;
            if(item != null && item.Element(element) != null)
            {
                results = item.Element(element).Value;
            }
            if (results == string.Empty)
            {
                results = defaultValue;
            }
            return results;
        }
        #endregion



        public static string GetUrlFromAnchor(string anchorTag)
        {
            if (anchorTag.Trim() == string.Empty)
                return anchorTag;
            //anchorTag = "<a href=\"http://www.tdameritrade.com/offer/global/img/gen-tdamtdlogo.gif\">http://www.tdameritrade.com/offer/global/img/gen-tdamtdlogo.gif</a>";
            anchorTag = anchorTag.Replace("<a href=\"", "");
            anchorTag = anchorTag.Substring(0,anchorTag.IndexOf("\">"));
            return anchorTag;
        }
    }
}
